﻿
using CSharpLibs.Annotations;

namespace System.IO
{
	[Builtin]
	public class BinaryReader : IDisposable
	{
		// Fields
		private byte[] m_buffer;
		private Stream m_stream;
		
		public BinaryReader(Stream input)
		{
			this.m_stream = input;
			this.m_buffer = new byte[0x10];
		}

		[BuiltinMethod, BuiltinSemantics("binaryconv_todouble")]
		private static double ConvertBitRepresentationToDouble(ulong bval)
		{ return 0.0; }

		[BuiltinMethod, BuiltinSemantics("binaryconv_tofloat")]
		private static float ConvertBitRepresentationToSingle(uint bval)
		{ return 0.0f; }

		public virtual void Close()
		{ this.Dispose(true); }

		public void Dispose()
		{ this.Dispose(true); }

		protected virtual void Dispose(bool disposing)
		{
			if(disposing)
			{
				Stream stream = this.m_stream;
				this.m_stream = null;
				stream.Close();
			}
			this.m_stream = null;
			this.m_buffer = null;
		}

		protected virtual void FillBuffer(int numBytes)
		{
			int offset = 0;
			int num2 = 0;
			if(numBytes == 1)
			{
				num2 = this.m_stream.ReadByte();
				this.m_buffer[0] = (byte)num2;
			}
			else
			{
				do
				{
					num2 = this.m_stream.Read(this.m_buffer, offset, numBytes - offset);
					offset += num2;
				}
				while(offset < numBytes);
			}
		}

		public virtual int Read()
		{
			return this.m_stream.ReadByte();
		}

		public virtual int Read(byte[] buffer, int index, int count)
		{ return this.m_stream.Read(buffer, index, count); }

		public virtual int Read(char[] buffer, int index, int count)
		{
			byte[] bb = new byte[buffer.Length];
			int rb = this.m_stream.Read(bb, index, count);

			for(int i = index; i < count; ++i)
				buffer[i] = (char)bb[i];

			return rb;
		}

		public virtual bool ReadBoolean()
		{
			this.FillBuffer(1);
			return (this.m_buffer[0] != 0);
		}

		public virtual byte ReadByte()
		{
			int num = this.m_stream.ReadByte();
			return (byte)num;
		}

		public virtual byte[] ReadBytes(int count)
		{
			byte[] buffer = new byte[count];
			int offset = 0;
			do
			{
				int num2 = this.m_stream.Read(buffer, offset, count);
				if(num2 == 0)
				{
					break;
				}
				offset += num2;
				count -= num2;
			}
			while(count > 0);
			return buffer;
		}

		public virtual char ReadChar()
		{
			int num = this.Read();
			return (char)num;
		}

		public virtual char[] ReadChars(int count)
		{
			byte[] bb = new byte[count];
			this.m_stream.Read(bb, 0, count);

			char[] rb = new char[count];
			for(int i = 0; i < count; ++i)
				rb[i] = (char)bb[i];

			return rb;
		}

		public virtual double ReadDouble()
		{
			this.FillBuffer(8);
			uint num = (uint)(((this.m_buffer[0] | (this.m_buffer[1] << 8)) | (this.m_buffer[2] << 0x10)) | (this.m_buffer[3] << 0x18));
			uint num2 = (uint)(((this.m_buffer[4] | (this.m_buffer[5] << 8)) | (this.m_buffer[6] << 0x10)) | (this.m_buffer[7] << 0x18));
			ulong num3 = (num2 << 0x20) | num;
			return ConvertBitRepresentationToDouble(num3);
		}

		public virtual short ReadInt16()
		{
			this.FillBuffer(2);
			return (short)(this.m_buffer[0] | (this.m_buffer[1] << 8));
		}

		public virtual int ReadInt32()
		{
			this.FillBuffer(4);
			return (((this.m_buffer[0] | (this.m_buffer[1] << 8)) | (this.m_buffer[2] << 0x10)) | (this.m_buffer[3] << 0x18));
		}

		public virtual long ReadInt64()
		{
			this.FillBuffer(8);
			uint num = (uint)(((this.m_buffer[0] | (this.m_buffer[1] << 8)) | (this.m_buffer[2] << 0x10)) | (this.m_buffer[3] << 0x18));
			uint num2 = (uint)(((this.m_buffer[4] | (this.m_buffer[5] << 8)) | (this.m_buffer[6] << 0x10)) | (this.m_buffer[7] << 0x18));
			return (long)((num2 << 0x20) | num);
		}

		public virtual sbyte ReadSByte()
		{
			this.FillBuffer(1);
			return (sbyte)this.m_buffer[0];
		}

		public virtual float ReadSingle()
		{
			this.FillBuffer(4);
			uint num = (uint)(((this.m_buffer[0] | (this.m_buffer[1] << 8)) | (this.m_buffer[2] << 0x10)) | (this.m_buffer[3] << 0x18));
			return ConvertBitRepresentationToSingle(num);
		}

		public virtual ushort ReadUInt16()
		{
			this.FillBuffer(2);
			return (ushort)(this.m_buffer[0] | (this.m_buffer[1] << 8));
		}

		public virtual uint ReadUInt32()
		{
			this.FillBuffer(4);
			return (uint)(((this.m_buffer[0] | (this.m_buffer[1] << 8)) | (this.m_buffer[2] << 0x10)) | (this.m_buffer[3] << 0x18));
		}

		public virtual ulong ReadUInt64()
		{
			this.FillBuffer(8);
			uint num = (uint)(((this.m_buffer[0] | (this.m_buffer[1] << 8)) | (this.m_buffer[2] << 0x10)) | (this.m_buffer[3] << 0x18));
			uint num2 = (uint)(((this.m_buffer[4] | (this.m_buffer[5] << 8)) | (this.m_buffer[6] << 0x10)) | (this.m_buffer[7] << 0x18));
			return ((num2 << 0x20) | num);
		}

		public virtual Stream BaseStream
		{ get { return this.m_stream; } }
	}
}
